package team.se.tms.controller.user;

import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import team.se.tms.annotation.CheckFormat;
import team.se.tms.annotation.Regex;
import team.se.tms.annotation.SpecialCheck;
import team.se.tms.constant.RoleConstant;
import team.se.tms.constant.SessionConstant;
import team.se.tms.constant.SystemConstant;
import team.se.tms.controller.BaseController;
import team.se.tms.dto.Page;
import team.se.tms.dto.ParameterMap;
import team.se.tms.dto.UserDetail;
import team.se.tms.enums.ResultEnum;
import team.se.tms.exception.InsertException;
import team.se.tms.exception.LoginException;
import team.se.tms.exception.SelectException;
import team.se.tms.exception.UpdateException;
import team.se.tms.po.RoleInfo;
import team.se.tms.po.UserInfo;
import team.se.tms.service.ImageInfoService;
import team.se.tms.service.RoleInfoService;
import team.se.tms.service.UserInfoService;
import team.se.tms.util.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpSession;
import java.util.List;


/**
 * 用户信息控制层
 *
 * @author winkyle
 * @date 2018/11/6
 */
@Slf4j
@Controller
@RequestMapping(value = "/user")
public class UserInfoController extends BaseController {

    @Autowired
    private ImageInfoService imageInfoService;

    @Resource(name = "UserInfoServiceImpl")
    private UserInfoService userInfoService;

    @Autowired
    private RoleInfoService roleInfoService;

    /**
     * 访问登录页,加载登录页数据
     *
     * @return String 页面地址
     * @throws Exception 异常
     * @create on 2018/11/6 by winkyle
     */
    @RequestMapping(value = "/to_login")
    public ModelAndView toLogin() throws Exception {
        log.debug("来到登录界面");
        ParameterMap parameterMap = getParameterMap();
        Jurisdiction.getSession().setAttribute(SessionConstant.DEPARTMENT, SystemConstant.DEPARTMENT);
        Jurisdiction.getSession().setAttribute(SessionConstant.SYSTEM_NAME, SystemConstant.SYSTEM_NAME);
        parameterMap.put("backgroundImages", imageInfoService.listImageInfos("login", true,null));
        ModelAndView modelAndView = getModelAndView();
        modelAndView.addObject("pageData",ResultUtil.success(parameterMap));
        modelAndView.setViewName("login");
        return modelAndView;
    }

    /**
     * 请求登录，验证用户
     *
     * @return json字符串
     * @throws Exception 异常
     * @create on 2018/11/6 by winkyle
     */
    @RequestMapping(value = "/login", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Object login(@Regex("^[a-zA-Z0-9]{8,16}$")String account,@Regex("^[a-zA-Z0-9]{6,16}$")String password,@Regex("^[a-zA-Z0-9]{4}$")String code) throws Exception {
        log.debug("登录者:{}，密码:{}，验证码:{}", account, password, code);
        String verificationCode = (String) Jurisdiction.getSession().getAttribute(SessionConstant.VERIFICATION_CODE);
        if (StringUtil.isEmpty(verificationCode) || !verificationCode.equalsIgnoreCase(code)) {
            throw new LoginException(ResultEnum.VERIFICATION_CODE_WRONG);
        }
        Subject subject = SecurityUtils.getSubject();
        UsernamePasswordToken token = new UsernamePasswordToken(account, password);
        token.setRememberMe(true);
        try {
            subject.login(token);
        } catch (UnknownAccountException e) {
            throw new LoginException(ResultEnum.ACCOUNT_NO_EXIST);
        } catch (IncorrectCredentialsException e) {
            throw new LoginException(ResultEnum.PASSWORD_WRONG);
        } catch (LockedAccountException e) {
            throw new LoginException(ResultEnum.ACCOUNT_LOCKED);
        } catch (DisabledAccountException e) {
            throw new LoginException(ResultEnum.ACCOUNT_DISABLED);
        } catch (ExcessiveAttemptsException e) {
            throw new LoginException(ResultEnum.EXCESSIVE_ATTEMPTS);
        } catch (AuthenticationException e) {
            throw new LoginException(ResultEnum.Error);
        }
        Jurisdiction.getSession().removeAttribute(SessionConstant.VERIFICATION_CODE);
        return ResultUtil.success("登录成功");
    }

    /**
     * 检查用户id是否正确
     *
     * @param userId
     * @return
     * @throws Exception
     * @create on 2018/12/2 by qingx
     */
    @RequestMapping("state")
    @ResponseBody
    public Object searchUserState(@Regex("^[A-Za-z0-9]{16}$")String userId) throws Exception{
        UserInfo user =  userInfoService.getUserState(userId);
        if (user == null){
            throw new SelectException("该用户不存在");
        }else if (user.getRoleId() == null || user.getRoleId().equals(RoleConstant.NULL)){
            return ResultUtil.success("用户id正确");
        }
        throw new SelectException("该用户已经分配角色");
    }

    /**
     * 去修改密码界面
     *
     * @return ModelAndView 页面和返回值
     * @throws Exception 异常
     * @create on 2018/12/20 by johnny
     */
    @RequestMapping("toEditPassword")
    public ModelAndView toEditUserPassword(){
        UserInfo userInfo = (UserInfo) Jurisdiction.getSession().getAttribute(SessionConstant.USER);
        String userId = userInfo.getUserId();
        ModelAndView mv = this.getModelAndView();
        mv.addObject("userId",userId);
        mv.setViewName("user/modify-password");
        return mv;
    }
    /**
     * 用户修改密码
     *
     * @param oldPassword 原始密码
     * @return newPassword 新密码
     * @throws Exception 异常
     * @create on 2018/12/20 by johnny
     */
    @RequestMapping("editPassword")
    @ResponseBody
    public Object editUserPassword(@Regex("^[A-Za-z0-9]{6,16}$") String oldPassword,@Regex("^[A-Za-z0-9]{6,16}$") String newPassword, HttpSession session) throws Exception{
        UserInfo userInfo = (UserInfo) Jurisdiction.getSession().getAttribute(SessionConstant.USER);
        String userId = userInfo.getUserId();
        //String userId = "2018111723242522";
        boolean result= userInfoService.modifyUserPassword(userId,oldPassword,newPassword);
        if(!result){
            return new UpdateException("账号或密码错误");
        }
        return ResultUtil.success();
    }

    //Jurisdiction.getSession().setAttribute(SessionConstant.USER,userInfo);

    /**
     * 分配角色前先查出所有用户编号、学号/工号、角色名
     *
     * @create on 2018/12/28 by argentum
     *
     * @param type 0为学生 1为老师
     * @param id 学号或工号
     * @param info 班级或授课名
     * @throws Exception 异常
     */
    @RequestMapping("listUserByAttr")
    @ResponseBody
    public Object searchUserDetails(Integer type, String id, String info,Page page) throws Exception{
        System.out.println(type+"==="+id+"==="+info+"===");

        List<UserDetail> userDetails = userInfoService.listUserInfos(page,type,id,info);
        return page.getDataTabelJson(userDetails);
    }

    @RequestMapping("listUser")
    @ResponseBody
    public Object searchUserDetails(Page page) throws Exception{
        List<UserDetail> userDetails =  userInfoService.listUserInfos(page);
        return page.getDataTabelJson(userDetails);
    }

    /**
     * to分配角色界面
     * @create on 2018/12/27 by argentum
     * @return
     * @throws Exception
     */
    @RequestMapping(value="toDistribute")
    @ResponseBody
    public Object toDistributeRole() throws Exception{
        ModelAndView mv = this.getModelAndView();
        List<RoleInfo> roles = roleInfoService.listAllRoleInfos();
        mv.addObject("roles",roles);
        mv.setViewName("role/distribute_role");
        return mv;
    }

    /**
     * @create on 2018/12/30 by argentum
     *
     * @param userIds
     * @param roleId
     * @return
     * @throws Exception
     */
    @RequestMapping("distributeRole")
    @ResponseBody
    public Object distributeRole(@RequestParam("userIds") List<String> userIds,@SpecialCheck("Pk")String roleId) throws Exception{
        System.out.println("userIds==========="+userIds);
        System.out.println("roleId==========="+roleId);
        Boolean success = userInfoService.modifyUserInfos(userIds, roleId);
        if(!success){
            throw new UpdateException();
        }
        return ResultUtil.success("分配成功");
    }

    /**
     * 跳转到录入用户页面
     * @return
     * @throws Exception
     * @create on 2018/12/30 by qingx
     */
    @RequestMapping("toAdd")
    public Object toAddUser() throws Exception{
        ModelAndView mv = this.getModelAndView();
        mv.addObject("userId", KeyUtil.generatePrimaryKey());
        List<RoleInfo> roleInfos = roleInfoService.listAllRoleInfos();
        System.out.println(roleInfos);
        mv.addObject("roleInfos", roleInfos);
        mv.setViewName("user/add_user");
        return mv;
    }


    /**
     * 录入用户信息
     *
     * @throws Exception 异常
     * @create on 2018/12/31 by qingx
     */
    @RequestMapping("addUser")
    @ResponseBody
    public Object addUserInfo(UserInfo user) throws Exception{
        System.out.println("==========================="+user);
        boolean result= userInfoService.savaUserInfo(user);
        if(result == true){
            return ResultUtil.success("用户录入成功");
        }
//        log.debug("上传了{},类型{}", multipartFile.getOriginalFilename(),multipartFile.getContentType());
       throw new InsertException("用户录入失败");
    }

}

